package da.metricscraft.client.frames;

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.util.*;
import java.util.Map.Entry;

import javax.swing.*;

import da.metricscraft.client.Constants;
import da.metricscraft.client.frames.SwitchPanel.ButtonActions;
import da.metricscraft.client.frames.layers.SpatialPlayerLayer;
import da.metricscraft.client.frames.layers.MovementLayer;
import da.metricscraft.client.threads.*;
import da.metricscraft.client.threads.SpatialXMLLoader.LocationStruct;
import da.metricscraft.client.threads.SpatialXMLLoader.MoveActions;
import da.metricscraft.client.threads.XMLLoader.LoaderTypes;
import da.metricscraft.client.tools.LoaderRow;

public class LoadingPanel extends JPanel implements KeyListener, ActionListener, ItemListener{
	/**
	 * 
	 */
	private static LoadingPanel currentPanel;
	private static final long serialVersionUID = 1L;
	private HashMap<MoveActions, LabelCheckboxRow> layerRows;
	private LoaderRow spatialLoaderRow;
	private LoaderRow playerLoaderRow;
	private LoaderRow biomesLoaderRow;
	private JComboBox<String> playerStatsBox;
	private JPanel containerPanel;
	private JPanel activatePlayersPanel;
	public static ImageIcon ICON_EMPTY;
	public static ImageIcon ICON_REFRESHING;
	public static ImageIcon ICON_REFRESH;
	public static ImageIcon ICON_CHECK;
	private XMLLoader<?> mLoader = new SpatialXMLLoader(LoaderTypes.SPATIAL);
	private XMLLoader<?> bLoader = new BiomsXMLLoader(LoaderTypes.BIOMS);
	private XMLLoader<?> pLoader = new PlayerXMLLoader(LoaderTypes.PLAYER);

	private class LabelCheckboxRow{
		public JCheckBox checkbox;
		public JLabel label;
		public LabelCheckboxRow(String name, ItemListener l){
			label = new JLabel(name);
			checkbox = new JCheckBox();
			checkbox.addItemListener(l);
		}
	}
	public static LoadingPanel getInstance(){
		if (currentPanel == null){
			currentPanel = new LoadingPanel();
		}
		return currentPanel;
	}
	public static enum Actions{
		MOVEMENT_SEARCH,
		MOVEMENT_REFRESH,
		MOVEMENT_ACTIVATE,
		BIOME_SEARCH,
		BIOME_REFRESH,
		PLAYERSTATS_SEARCH,
		PLAYERSTATS_REFRESH,
		CancelSelection

	}
	public LoadingPanel(){
		ICON_EMPTY = createImageIcon("empty.png");
		ICON_REFRESH = createImageIcon("arrow_cycle.png");
		ICON_REFRESHING = createImageIcon("ajax_loader_big.gif");
		ICON_CHECK = createImageIcon("check.png");

		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		layerRows = new HashMap<SpatialXMLLoader.MoveActions, LoadingPanel.LabelCheckboxRow>();
		containerPanel = new JPanel();
		containerPanel.setLayout(new GridLayout(10,1));
		containerPanel.setPreferredSize(new Dimension(getWidth() - 10, getHeight()/6));
		spatialLoaderRow = new LoaderRow(mLoader, "MOVEMENT");
		biomesLoaderRow = new LoaderRow(bLoader, "BIOME");
		playerLoaderRow = new LoaderRow(pLoader, "PLAYERSTATS");
		for (MoveActions action : MoveActions.values()){
			if (action == MoveActions.NONE || action == MoveActions.MOVE) continue;
			layerRows.put(action, new LabelCheckboxRow(action.name(), this));
		}


		biomesLoaderRow.refreshButton.setEnabled(true);
		containerPanel.add(createLoadingRow("Biomes:", Constants.FILEPATHS.BIOMES.Path() ,
				biomesLoaderRow, Actions.BIOME_SEARCH, Actions.BIOME_REFRESH, null));
		containerPanel.add(createLoadingRow("Playerstats:", Constants.FILEPATHS.PLAYER.Path(), 
				playerLoaderRow, Actions.PLAYERSTATS_SEARCH, Actions.PLAYERSTATS_REFRESH, null));

		JPanel pan = new JPanel();
		pan.setLayout(new FlowLayout(FlowLayout.LEFT));
		pan.add(new JLabel(LoadingPanel.ICON_EMPTY));
		pan.add(new JLabel(LoadingPanel.ICON_EMPTY));
		pan.add(new JLabel(LoadingPanel.ICON_EMPTY));
		pan.add(new JLabel("Display player: "));
		playerStatsBox = new JComboBox<String>();
		playerStatsBox.setEnabled(false);
		playerStatsBox.setPreferredSize(new Dimension(200, 20));
		playerStatsBox.addActionListener(this);
		pan.add(playerStatsBox);
		containerPanel.add(pan);

		containerPanel.add(createLoadingRow("Spatial Actions:", Constants.FILEPATHS.MOVEMENT.Path(), 
				spatialLoaderRow, Actions.MOVEMENT_SEARCH, Actions.MOVEMENT_REFRESH, Actions.MOVEMENT_ACTIVATE));
		JLabel temp = new JLabel("Select location for XML files to calculate with");
		temp.setAlignmentX(CENTER_ALIGNMENT);
		add(temp);
		add(containerPanel);

		activatePlayersPanel = new JPanel();
		activatePlayersPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
		activatePlayersPanel.setPreferredSize(new Dimension(getWidth() - 10, getHeight()));
		JLabel test = new JLabel();
		test.setPreferredSize(new Dimension(getWidth() - 10, getHeight()*3/4));
		activatePlayersPanel.add(test);
		temp = new JLabel("Layers");
		temp.setAlignmentX(CENTER_ALIGNMENT);
		add(temp);
		add(activatePlayersPanel);
		//add(new JPanel());
		mLoader.addFinishListener(this);
		bLoader.addFinishListener(this);
		pLoader.addFinishListener(this);
		mLoader.start();
		bLoader.start();
		pLoader.start();
		playerLoaderRow.refreshButton.setEnabled(true);
		setPreferredSize(new Dimension(425, 700));
		LoadingPanel.currentPanel = this;
	}

	private JPanel createLoadingRow(String name, String presetPath, LoaderRow row, Actions searchCommand, Actions refreshCommand, Actions activateCommand) {
		JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		row.textField.setText(presetPath);
		JLabel label = new JLabel(name);
		label.setPreferredSize(new Dimension(75,25));
		row.refreshButton.setIcon(ICON_REFRESH); //remove after testing
		row.refreshButton.setActionCommand(refreshCommand.name());
		row.refreshButton.addActionListener(this);
		row.fileChooser.addActionListener(this);
		label.setSize(100, label.getSize().height);
		row.textField.setColumns(20);
		row.textField.addKeyListener(this);
		row.checkBox.setVisible(true);
		row.checkBox.addItemListener(this);
		JButton browseButton = new JButton(UIManager.getIcon("Tree.openIcon"));
		browseButton.setActionCommand(searchCommand.name());
		browseButton.addActionListener(this);

		panel.add(row.checkBox);
		panel.add(label);
		panel.add(row.textField);
		panel.add(browseButton);
		panel.add(row.refreshButton);
		panel.add(row.label);
		return panel;
	}

	private ImageIcon createImageIcon(String path) {
		java.net.URL imgURL = getClass().getClassLoader().getResource("da/metricscraft/client/icons/" + path);
		if (imgURL != null) {
			ImageIcon ii = new ImageIcon(imgURL);

			return ii;
		} else {
			System.err.println("Couldn't find file: " + path);
			return null;
		}
	}
	private void createLayerRows(JPanel panel){
		for (LabelCheckboxRow r : layerRows.values()){
			JPanel temppane = new JPanel(new FlowLayout(FlowLayout.LEFT));
			r.checkbox.setEnabled(false);
			r.label.setPreferredSize(new Dimension(150,10));
//
//			temppane.add(new JLabel(LoadingPanel.ICON_EMPTY));
//			temppane.add(new JLabel(LoadingPanel.ICON_EMPTY));
			temppane.add(r.checkbox);
			temppane.add(r.label);
			panel.add(temppane);
		}
	}
	public void finishedLoading(XMLLoader<?> loader){
		switch(loader.getType()){
		case BIOMS:
			SwitchPanel.getInstance().enableButton(ButtonActions.GRAPHICS);
			GraphicsPanel.getInstance().setEnabled(true);

			System.out.println("reloading loader list");
			GraphicsPanel.getInstance().reloadList((BiomsXMLLoader)loader, ((BiomsXMLLoader)loader).getLowest(), ((BiomsXMLLoader)loader).getHighest());
			GraphicsPanel.getInstance().loadLayers();
			spatialLoaderRow.refreshButton.setEnabled(true);
			biomesLoaderRow.checkBox.setEnabled(true);
			biomesLoaderRow.finished();
			biomesLoaderRow.checkBox.setSelected(true);
			loader.releaseXml();
			break;
		case SPATIAL:
			MovementLayer.getInstance()
			.setData(((SpatialXMLLoader)loader)
					.getData());
			HashMap<String, ArrayList<LocationStruct>>  data = ((SpatialXMLLoader)loader).getData();
			ArrayList<String> players = new ArrayList<String>();
			players.addAll(((SpatialXMLLoader)loader).getData().keySet());

			if (activatePlayersPanel != null)
				activatePlayersPanel.removeAll();

			JPanel layerPanel = new JPanel();
			layerPanel.setPreferredSize(new Dimension(getWidth()/2 - 10, getHeight()/2));
			layerPanel.setLayout(new GridLayout(15, 1));
			createLayerRows(layerPanel);
			JPanel playerPanel = new JPanel();
			playerPanel.setPreferredSize(new Dimension(getWidth()/2 - 10, getHeight()/2));
			playerPanel.setLayout(new GridLayout(15, 1));
			for (String player : players){
				JPanel p = new JPanel();
				p.setLayout(new FlowLayout(FlowLayout.LEFT));
				LabelCheckboxRow r = new LabelCheckboxRow(player, this);
				r.label.setPreferredSize(new Dimension(100,15));
				r.checkbox.addItemListener(this);
				r.checkbox.setSelected(true);
				r.checkbox.setName("player_" + player);
				p.add(r.label);
				p.add(r.checkbox);
				playerPanel.add(p);
			}
			layerPanel.revalidate();
			playerPanel.revalidate();
			activatePlayersPanel.add(layerPanel);
			activatePlayersPanel.add(playerPanel);

			activatePlayersPanel.revalidate();
			revalidate();


			for (Entry<MoveActions, LabelCheckboxRow> entry : layerRows.entrySet()){
				SpatialPlayerLayer layer = SpatialPlayerLayer.getInstance(entry.getKey());
				layer.setData(data);
				if (layer.getIsAvailable()){
					entry.getValue().checkbox.setEnabled(true);
				}else{
					System.out.println("[LoadingPanel][finishedLoading] Not available: " + entry.getKey());
				}
			}
			spatialLoaderRow.checkBox.setEnabled(true);
			spatialLoaderRow.finished();
			loader.releaseXml();
			break;
		case PLAYER:
			SwitchPanel.getInstance().enableButton(ButtonActions.STATS);
			StatsPanel.getInstance().setEnabled(true);
			StatsPanel.getInstance().setData((PlayerXMLLoader)loader);
			players = new ArrayList<String>();
			players.addAll(((PlayerXMLLoader)loader).getData().keySet());
			playerStatsBox.removeAllItems();
			for (String item : players)
				playerStatsBox.addItem(item);
					playerStatsBox.setEnabled(true);
					playerLoaderRow.finished();
					loader.releaseXml();
					break;
		}
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println(e.getActionCommand());
		//
		// TODO Auto-generated method stub
		if (e.getActionCommand() == JFileChooser.APPROVE_SELECTION){
			if (e.getSource() == biomesLoaderRow.fileChooser){
				biomesLoaderRow.approve();
			}else if (e.getSource() == spatialLoaderRow.fileChooser){
				spatialLoaderRow.approve();
			}else if (e.getSource() == playerLoaderRow.fileChooser){
				playerLoaderRow.approve();
			}
			return;
		}
		if (e.getSource() instanceof JComboBox){
			JComboBox<?> cb = (JComboBox<?>)e.getSource();
			if (cb.getSelectedItem() != null){
				StatsPanel.getInstance().setPlayer((String)cb.getSelectedItem());
			}
			System.out.println("Combobox event: " + e.getActionCommand() + " | " + cb.getSelectedItem());
			return;
		}

		Actions action = Actions.valueOf(e.getActionCommand());
		System.out.println("Doing action: " + action.name());
		spatialLoaderRow.doAction(action);
		biomesLoaderRow.doAction(action);
		playerLoaderRow.doAction(action);
	}
	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void keyPressed(KeyEvent e) {
		if (e.getSource() == spatialLoaderRow.textField)
			spatialLoaderRow.label.setIcon(ICON_EMPTY);
		else if (e.getSource() == biomesLoaderRow.textField)
			biomesLoaderRow.label.setIcon(ICON_EMPTY);
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void itemStateChanged(ItemEvent e) {

		// TODO Auto-generated method stub
		Object source = e.getItemSelectable();
		if (source == spatialLoaderRow.checkBox){
			MovementLayer.getInstance().setActive(e.getStateChange() != ItemEvent.DESELECTED);
		}else if (source == biomesLoaderRow.checkBox){
			GraphicsPanel.getInstance().setActive(e.getStateChange() != ItemEvent.DESELECTED);
		
		}else {
			if (source instanceof JCheckBox && ((JCheckBox) source).getName() != null){
				JCheckBox s = (JCheckBox)source;
				if (s.getName().contains("player_")){
					if (e.getStateChange() == ItemEvent.DESELECTED){
						MovementLayer.getInstance().hidePlayer(s.getName().replace("player_", ""));
						for(MoveActions a : MoveActions.values()){
							SpatialPlayerLayer l = SpatialPlayerLayer.getInstance(a); 
							if (l != null) l.hidePlayer(s.getName().replace("player_", ""));
						}
					}else if (e.getStateChange() == ItemEvent.SELECTED){
						MovementLayer.getInstance().showPlayer(s.getName().replace("player_", ""));
						for(MoveActions a : MoveActions.values()){
							SpatialPlayerLayer l = SpatialPlayerLayer.getInstance(a); 
							if (l != null) l.showPlayer(s.getName().replace("player_", ""));
						}
					}
				}

			}
			for (Entry<MoveActions, LabelCheckboxRow> entry : layerRows.entrySet()){

				if (entry.getKey() == MoveActions.NONE || entry.getKey() == MoveActions.MOVE) continue;
				if (source == entry.getValue().checkbox){

					if (e.getStateChange() == ItemEvent.DESELECTED){
						SpatialPlayerLayer.getInstance(entry.getKey()).setActive(false);
					}else if (e.getStateChange() == ItemEvent.SELECTED){
						SpatialPlayerLayer.getInstance(entry.getKey()).setActive(true);
					}
				}
			}
		}
	}
}
